/**
 * AbstractMemoryDao.java 1.0 2007-5-17 上午02:25:57,创建 by yangfan
 */


package org.in4j.core.dao;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Query;
import org.hibernate.criterion.DetachedCriteria;
import org.in4j.core.dao.support.Pagination;

/**
 *
 * @author yangfan
 * @version 1.0 2007-5-17 上午02:25:57,创建
 */
public abstract class AbstractMemoryDao<T> implements BaseDao<T>
{
	@SuppressWarnings("unused")
	private static final Log log = LogFactory.getLog(AbstractMemoryDao.class);

	private final Map<Serializable,T> db = new HashMap<Serializable, T>();
	private int sequence = 1;
	private Class<T> entityClass;

	public AbstractMemoryDao()
	{
		this.entityClass = (Class<T>)((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];
	}

	public void create(T entity)
	{
		final Serializable id = getNextId();
		try
		{
			BeanUtils.setProperty(entity, getIdentityName(), id);
		}
		catch(Exception ex)
		{
			throw new IllegalArgumentException("创建实体对象 " + entity + "失败,该对象没有id属性?.",ex);
		}
		db.put(id, entity);
	}

	protected Class getEntityClass()
	{
		return entityClass;
	}

	public T getById(Serializable id)
	{
		return db.get(id);
	}

	public T load(Serializable id)
	{
		T entity = db.get(id);
		if(entity == null) throw new NullPointerException("未找到对应id=" + id + " 的对象.");
		return entity;
	}

	private T loadEntity(T entity)
	{
		Serializable id = (Serializable)getPropertyValue(entity,getIdentityName());
		T result = db.get(id);
		if(result == null) throw new NullPointerException("未找到对应id=" + id + " 的对象.");
		return result;
	}

	public void remove(T entity)
	{
		try
		{
			T bean = loadEntity(entity);
			Serializable id = (Serializable)getPropertyValue(bean,getIdentityName());
			db.remove(id);
		}
		catch(IllegalArgumentException ex)
		{
			throw new IllegalArgumentException("移除实体对象 " + entity + "失败,未取到该对象id属性值.",ex);
		}
	}

	/**
	 * 覆盖此方法,即可指定自己的主键名字
	 * @return 主键字段名,默认为id
	 */
	protected String getIdentityName()
	{
		return "id";
	}

	public void removeById(Serializable id)
	{
		db.remove(id);
	}

	public DetachedCriteria createDetachedCriteria()
	{
		// TODO 自动生成方法存根
		if(true)
			throw new UnsupportedOperationException();
		return null;
	}

	public Query createQuery(String hql, Object... values)
	{
		// TODO 自动生成方法存根
		if(true)
			throw new UnsupportedOperationException();
		return null;
	}

	public List find(String hql, Object... values)
	{
		// TODO 自动生成方法存根
		if(true)
			throw new UnsupportedOperationException();
		return null;
	}

	public Pagination findPageByCriteria(DetachedCriteria detachedCriteria)
	{
		// TODO 自动生成方法存根
		if(true)
			throw new UnsupportedOperationException();
		return null;
	}

	public Pagination findPageByCriteria(DetachedCriteria detachedCriteria, int startIndex)
	{
		// TODO 自动生成方法存根
		if(true)
			throw new UnsupportedOperationException();
		return null;
	}

	public Pagination findPageByCriteria(DetachedCriteria detachedCriteria, int startIndex, int pageSize)
	{
		// TODO 自动生成方法存根
		if(true)
			throw new UnsupportedOperationException();
		return null;
	}

	public <ObjectType> ObjectType uniqueResult(String hql, Object... values)
	{
		// TODO 自动生成方法存根
		if(true)
			throw new UnsupportedOperationException();
		return null;
	}

	public void update(T entity)
	{
		T orignal = loadEntity(entity);
		try
		{
			BeanUtils.copyProperties(orignal, entity);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}

	private synchronized Serializable getNextId()
	{
		return sequence++;
	}

	private Object getPropertyValue(Object entity, String property) throws IllegalArgumentException
	{
		try
		{
			return PropertyUtils.getProperty(entity, property);
		}
		catch(Exception ex)
		{
			throw new IllegalArgumentException("取不到对象 " + entity + " 的属性值[" + property + "]",ex);
		}
//		PropertyDescriptor descriptor = BeanUtils.getPropertyDescriptor(getEntityClass(), "id");
//		if(descriptor == null) throw
//		Method getter = descriptor.getReadMethod();
//		if(!getter.isAccessible())
//			getter.setAccessible(true);
//		return getter.invoke(entity, (Object)null);
	}

}
